#ifndef FMT_INCLUDED
#define FMT_INCLUDED

#include "except.h"

#include <stdarg.h>
#include <stdio.h>

typedef struct va_list_box {
    va_list ap;
} va_list_box;

#define T Fmt_T
typedef void (*T)(int code, va_list_box *box,
                  int put(int c, void *cl), void *cl,
                  unsigned char flags[256], int width, int precision);

extern const char *Fmt_flags;
extern const Except_T Fmt_Overflow;

void Fmt_fmt(int put(int c, void *cl), void *cl, const char *fmt, ...);
void Fmt_vfmt(int put(int c, void *cl), void *cl, const char *fmt, va_list_box *box);

void Fmt_print(const char *fmt, ...);
void Fmt_fprint(FILE *stream, const char *fmt, ...);

int Fmt_sfmt(char *buf, int size, const char *fmt, ...);
int Fmt_vsfmt(char *buf, int size, const char *fmt, va_list_box *box);

char* Fmt_string(const char *fmt, ...);
char* Fmt_vstring(const char *fmt, va_list_box *box);

T Fmt_register(int code, T newcvt);

void Fmt_putd(const char *str, int len,
              int put(int c, void *cl), void *cl,
              unsigned char flags[256], int width, int precision);
void Fmt_puts(const char *str, int len,
              int put(int c, void *cl), void *cl,
              unsigned char flags[256], int width, int precision);

#undef T

#endif

